/*
 * Copyright (C) 2024 ~ 2025 Deepin Technology Co., Ltd.
 *
 * Author:     zhangbingyi <zhangbingyi@uniontech.com>
 *
 * Maintainer: zhangbingyi <zhangbingyi@uniontech.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "antiviruswork.h"
#include "comdata.h"
#include "widgets/dialogmanage.h"
#include "common.h"
#include "invokers/invokerfactory.h"
#include "dversionnumber.h"

#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QDateTime>
#include <QTimer>

// gsetting上次检测时间键
const QString SLastScanTimeKey = "last-scan-time";

AntiVirusWork::AntiVirusWork(QObject *parent)
    : QObject(parent)
    , m_monitorInterFaceServer(nullptr)
    , m_virusScanServer(nullptr)
    , m_dataInterFaceServer(nullptr)
    , m_gsetting(nullptr)
    , m_mainWindowServer(nullptr)
    , m_notifDBusInter(nullptr)
    , m_sSrvVdbVer(antiav_localVdbDefaultVer)
    , m_sLocalVdbVer(antiav_localVdbDefaultVer)
    , m_threatsOperationStatus(false)
    , m_updateVdb(false)
    , m_needUpdate(false)
    , m_vdbChecking(false)
    , m_isFlag(false)
{
    // 安全中心gsetting
    m_gsetting = InvokerFactory::GetInstance().CreateSettings("com.deepin.dde.deepin-defender", QByteArray(), this);

    // 流量监控dbus接口
    m_monitorInterFaceServer = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.MonitorNetFlow",
                                                                           "/com/deepin/defender/MonitorNetFlow",
                                                                           "com.deepin.defender.MonitorNetFlow",
                                                                           ConnectType::SYSTEM, this);
    // 安全中心数据服务dbus接口
    m_dataInterFaceServer = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.datainterface",
                                                                        "/com/deepin/defender/datainterface",
                                                                        "com.deepin.defender.datainterface",
                                                                        ConnectType::SESSION, this);
    // 主窗口dbus接口
    m_mainWindowServer = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.hmiscreen",
                                                                     "/com/deepin/defender/hmiscreen",
                                                                     "com.deepin.defender.hmiscreen",
                                                                     ConnectType::SESSION, this);

    m_dataInterFaceServer->Connect("NotifyVirusSrvVersion", this, SLOT(acceptVirusSrvVersion(const QString &)));

    // 系统通知dbus对象
    m_notifDBusInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.dde.Notification",
                                                                   "/com/deepin/dde/Notification",
                                                                   "com.deepin.dde.Notification",
                                                                   ConnectType::SESSION, this);

    // 获取当前引擎类型
    QDBusMessage currentEngineMsg = DBUS_BLOCK_INVOKE(m_dataInterFaceServer, "GetCurrentEngine");
    GET_MESSAGE_VALUE(int, iEnginType, currentEngineMsg);
    m_currentEnginType = EnginType(iEnginType);

    if (EnginType::Rising == m_currentEnginType) {
        // 瑞星病毒查杀服务dbus接口
        m_virusScanServer = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.risantiav",
                                                                        "/com/deepin/defender/risantiav",
                                                                        "com.deepin.defender.risantiav",
                                                                        ConnectType::SYSTEM, this);
    } else if (EnginType::Ahprotector == m_currentEnginType) {
        m_virusScanServer = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.antiav",
                                                                        "/com/deepin/defender/antiav",
                                                                        "com.deepin.defender.antiav",
                                                                        ConnectType::SYSTEM, this);
    }

    queryVersionStatus();

    // 由于usb扫描不需要开启页面  所以在在usb扫描中不能设置停止
    QDBusMessage timerScaningMsg = DBUS_BLOCK_INVOKE(m_dataInterFaceServer, "IsTimerScaning");
    GET_MESSAGE_VALUE(bool, bIsTimerScan, timerScaningMsg);
    if (getCurrentScanStatus() != ScanStatus::UsbScanning && !bIsTimerScan) {
        // 对服务初始化 先停止扫描所有的任务，然后设置当前是空闲状态状态
        setCurrentScanStatus(ScanStatus::Free);
    }
    // 获得本地病毒库版本
    readLocalVdbVersion();
    // 获得服务器病毒库版本
    readSrvVdbVersion();

    /**********　瑞星信号　*********/
    // 瑞星服务返回的信号
    m_virusScanServer->Connect("SendDissectionProgInfo", this, SLOT(onRecDissectionResult(QString, double, int, QString)));
    // 结束信号
    m_virusScanServer->Connect("DissectionFinished", this, SLOT(onScanFinished()));
    // 接受瑞星病毒库服务更新成功信号
    m_virusScanServer->Connect("SendUpdateVersionResult", this, SLOT(onUpdateVDbFinished(bool)));
    m_virusScanServer->Connect("SendUpdateVersionResult", this, SLOT(updateVdbFinished(bool)));

    // 连接获取信任文件信号
    m_virusScanServer->Connect("SendQueryTrustFiles", this, SLOT(onRecTrustFiles(QString)));
    // 连接获取隔离文件信号
    m_virusScanServer->Connect("SendQueryIsolationFiles", this, SLOT(onRecIsolationFiles(QString)));

    //连接修复文件结果信号
    m_virusScanServer->Connect("SendOperationRepairFileResult", this, SLOT(sendRepairProblemFileResult(QString)));

    // 连接修改信任文件结果信号
    m_virusScanServer->Connect("SendOperationTrustFileResult", this, SLOT(sendChangeTrustFilesResult(QString)));

    // 连接获取隔离文件信号
    m_virusScanServer->Connect("SendOperationIsolationFileResult", this, SLOT(sendChangeIsolationFilesResult(QString)));

    // 连接更新信任区大小信号
    m_virusScanServer->Connect("SendTrustAreaSize", this, SLOT(notifyUpdateTrustAreaSize(int)));

    // 连接更新隔离区大小信号
    m_virusScanServer->Connect("SendIsolationAreaSize", this, SLOT(notifyUpdateIsolationAreaSize(int)));

    // 扫描状态设置完成后
    m_virusScanServer->Connect("SetScanStatusFinished", this, SLOT(onSetScanStatusFinished(int)));

    qDebug() << m_gsetting->GetValue(SAFETY_SCORE).toInt();
}

AntiVirusWork::~AntiVirusWork()
{
}

// 扫描
void AntiVirusWork::doDissection(bool isbAll, QString sPaths)
{
    m_isFlag = true;
    // 每次发送扫描的时候进行数据列表的清空
    m_threatsFileList.clear();
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "DoDissection", isbAll, sPaths);
    Q_EMIT notifyUpdateBackButton();
}

// 快速扫描
void AntiVirusWork::doQuickScan()
{
    QString quick = "/usr/bin*/usr/sbin*/usr/local*/tmp";
    doDissection(false, quick);
}

// 修复问题文件
void AntiVirusWork::requestRepairProblemFile(QString sPath)
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "RepairProblemFile", sPath);
}

// 操作信任文件是添加还是移除
void AntiVirusWork::requestChangeTrustFiles(bool isbAdd, QString sPath)
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "TrustProblemFile", isbAdd, sPath);
}

// 查询信任区域文件
void AntiVirusWork::requestQueryTrustFiles()
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "QueryTrustFiles");
}

// 操作隔离文件是添加还是移除
void AntiVirusWork::requestChangeIsolationFile(bool isbAdd, QString sPath)
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "IsolationProblemFile", isbAdd, sPath);
}

// 查询新的隔离区域文件
void AntiVirusWork::requestQueryIsolationFile()
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "QueryIsolationFiles");
}

// 是否正在操作隔离或信任区文件
bool AntiVirusWork::isOperatingIsolateTrustFiles()
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_virusScanServer, "IsOperatingFiles");
    GET_MESSAGE_VALUE(bool, operating, msg);
    return operating;
}

// 获取上次扫描时间
QString AntiVirusWork::lastScanningTime()
{
    return m_gsetting->GetValue(SLastScanTimeKey).toString();
}

// 获得当前病毒引擎
EnginType AntiVirusWork::getVriusType()
{
    return m_currentEnginType;
}

// 获取系统架构
QString AntiVirusWork::getSystemArch()
{
    if (m_systemArchitecture.isEmpty()) {
        QDBusMessage msg = DBUS_BLOCK_INVOKE(m_dataInterFaceServer, "GetSystemArchitecture");
        GET_MESSAGE_VALUE(QString, systemArchitecture, msg);
        m_systemArchitecture = systemArchitecture;
    }
    return m_systemArchitecture;
}

// 设置上次扫描时间
void AntiVirusWork::setLastScanningTime(QString sTime)
{
    m_gsetting->SetValue(SLastScanTimeKey, sTime);
}

// 以当前时间更新上次扫描时间
void AntiVirusWork::updateLastScanningTime()
{
    QDateTime date = QDateTime::currentDateTime();
    QString sLastScanningTime = date.toString("yyyy-MM-dd hh:mm:ss");
    // 设置上次扫描时间
    setLastScanningTime(sLastScanningTime);
    Q_EMIT notifyUpdateAntiVirusHomeUI();
}

// 更新病毒库
void AntiVirusWork::requestUpdateVirusDb()
{
    // 设置病毒库更新地址地址
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "SetVriusUpdateAddress", getVirusAddress());

    // 更新病毒库
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "UpdateVersion");

    // 设置当前状态是 病毒更新状态
    setCurrentScanStatus(ScanStatus::VdbUpdating);
    m_updateVdb = true;
    // 通知病毒查杀首页更新页面数据
    Q_EMIT notifyUpdateAntiVirusHomeUI();
}

void AntiVirusWork::scanThreatsFile()
{
    Q_EMIT sendRequstScanThreatsFile();
}

// 查询信任区的数量
void AntiVirusWork::selectTrustAreaSize()
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "SelectTrustAreaSize");
}

// 查询隔离区域的数量
void AntiVirusWork::selectIsolationAreaSize()
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "SelectIsolationAreaSize");
}

// 设置扫描状态
void AntiVirusWork::setCurrentScanStatus(ScanStatus status)
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "SetScanStatus", status);
}

// 获得扫描状态
ScanStatus AntiVirusWork::getCurrentScanStatus()
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_virusScanServer, "GetScanStatus");
    GET_MESSAGE_VALUE(int, iScanStatus, msg);
    return ScanStatus(iScanStatus);
}

// 接受扫描结束
void AntiVirusWork::onScanFinished()
{
    m_isFlag = false;
    Q_EMIT sendResultWhileScanFinished(m_threatsFileList);
}

// 病毒引擎扫描状态设置完成时
void AntiVirusWork::onSetScanStatusFinished(int status)
{
    Q_UNUSED(status);
    // 扫描状态设置完成后，更新主界面标题栏后退按钮
    updateBackButton();
}

// 更新返回按钮
void AntiVirusWork::updateBackButton()
{
    Q_EMIT notifyUpdateBackButton();
}

// 设置文件大小
void AntiVirusWork::setScanFileSize(int value, int showValue, bool status)
{
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "SetScanFileSize", value);

    QDBusVariant dbusVar(value);
    // 装载到QVariant
    QVariant var;
    var.setValue(dbusVar);
    // 记录设置的大小
    DBUS_NOBLOCK_INVOKE(m_monitorInterFaceServer, "SetSysSettingValue", VIURS_SCAN_SIZE, var);

    QDBusVariant dbusVarShow(showValue);
    // 装载到QVariant
    QVariant varShow;
    varShow.setValue(dbusVarShow);
    // 记录设置的大小
    DBUS_NOBLOCK_INVOKE(m_monitorInterFaceServer, "SetSysSettingValue", SHOW_SCAN_SIZE, varShow);

    QDBusVariant dbusVarStatus(status);
    // 装载到QVariant
    QVariant varStatus;
    varStatus.setValue(dbusVarStatus);
    // 记录设置的大小
    DBUS_NOBLOCK_INVOKE(m_monitorInterFaceServer, "SetSysSettingValue", EXECUTE_SCAN_SIZE, varStatus);
}

// 设置异常处理状态
void AntiVirusWork::setThreatsOperationStatus(bool flag)
{
    m_threatsOperationStatus = flag;
}

// 获得异常处理状态 true 处理中
bool AntiVirusWork::getThreatsOperationStatus()
{
    return m_threatsOperationStatus;
}

// 跳转到应用商店
void AntiVirusWork::jumpToAppStore()
{
    if (EnginType::Ahprotector == getVriusType()) {
        DBUS_NOBLOCK_INVOKE(m_dataInterFaceServer, "JumpToAppStore", Das_Security_Type);
    } else {
        DBUS_NOBLOCK_INVOKE(m_dataInterFaceServer, "JumpToAppStore", Rising_Type);
    }
}

// 设置病毒库地址
void AntiVirusWork::setVriusUpdateAddress(QString address)
{
}

// 接受扫描结果数据
void AntiVirusWork::onRecDissectionResult(QString sPath, double dProgress, int iType, QString sDetailInfo)
{
    // 病毒引擎
    if (EnginType::Rising == getVriusType()) {
        // 当前文件类型
        RisingVirusType currentType = RisingVirusType(iType);
        // 如果是异常
        if (RisingVirusType::RSmkTrusted != currentType) {
            m_threatsFileList.append(sPath);
        }
    } else {
        // 当前文件类型
        AHVirusType currentType = AHVirusType(iType);
        // 如果是异常
        if (AHVirusType::AHNormal != currentType) {
            m_threatsFileList.append(sPath);
        }
    }

    // 只有处于普通扫描，才向病毒查杀界面发送信号
    if (m_isFlag) {
        Q_EMIT sendDissectionResult(sPath, dProgress, iType, sDetailInfo);
    }
}

void AntiVirusWork::onRecTrustFiles(QString sInfos)
{
    QList<TrustFileInfo> trustFileInfos;
    // 接受数据分割为一个一个信息
    QStringList firstCutStrList = sInfos.split("[*]");
    for (QString infoStr : firstCutStrList) {
        QStringList secondCutStrList = infoStr.split("*");
        if (2 > secondCutStrList.size())
            continue;
        TrustFileInfo info;
        info.sFilePath = secondCutStrList.at(0);
        info.sFileName = info.sFilePath.split("/").last();
        info.sAddTime = secondCutStrList.at(1);
        //添加到信任列表
        trustFileInfos.append(info);
    }
    Q_EMIT sendTrustFilesByList(trustFileInfos);
}

void AntiVirusWork::onRecIsolationFiles(QString sInfos)
{
    QList<TrustFileInfo> isolationFileInfos;
    // 接受数据分割为一个一个信息
    QStringList firstCutStrList = sInfos.split("[*]");
    for (QString infoStr : firstCutStrList) {
        QStringList secondCutStrList = infoStr.split("*");
        if (2 > secondCutStrList.size())
            continue;
        TrustFileInfo info;
        info.sFilePath = secondCutStrList.at(0);
        info.sFileName = info.sFilePath.split("/").last();
        info.sAddTime = secondCutStrList.at(1);
        //添加到信任列表
        isolationFileInfos.append(info);
    }
    Q_EMIT sendIsolationFilesByList(isolationFileInfos);
}

void AntiVirusWork::onUpdateVDbFinished(bool isbSus)
{
    // 病毒更新完成以后 无论成功还是失败都是空闲状态
    setCurrentScanStatus(ScanStatus::Free);
    m_updateVdb = false;
    if (isbSus) {
        m_needUpdate = false;
        m_sLocalVdbVer = m_sSrvVdbVer;

        if (EnginType::Rising == getVriusType()) {
            m_gsetting->SetValue(RISING_LOCAL_VERSION, m_sSrvVdbVer);
        } else {
            m_gsetting->SetValue(AH_LOCAL_VERSION, m_sSrvVdbVer);
        }
    } else {
        m_needUpdate = true;
        // 若更新失败，则通知打开更新失败弹窗
        DialogManage dialog;
        dialog.showNormalTipDialog(IconTip, TipNetWorkEroor);
    }
    // 通知更新病毒查杀首页数据
    Q_EMIT notifyUpdateAntiVirusHomeUI();

    // 添加安全日志
    if (EnginType::Rising == getVriusType()) {
        DBUS_NOBLOCK_INVOKE(m_monitorInterFaceServer, "AddSecurityLog", SECURITY_LOG_TYPE_ANTIAV, tr("Updated Rising virus database to: %1").arg(m_sSrvVdbVer));
    } else {
        DBUS_NOBLOCK_INVOKE(m_monitorInterFaceServer, "AddSecurityLog", SECURITY_LOG_TYPE_ANTIAV, tr("Updated DAS-security virus database to: %1").arg(m_sSrvVdbVer));
    }
}

// 获得本地病毒库版本
void AntiVirusWork::readLocalVdbVersion()
{
    // 判断病毒引擎类型
    if (EnginType::Rising == getVriusType()) {
        // 获得瑞星本地版本
        m_sLocalVdbVer = m_gsetting->GetValue(RISING_LOCAL_VERSION).toString();
    } else {
        m_sLocalVdbVer = m_gsetting->GetValue(AH_LOCAL_VERSION).toString();
    }
}

// 获得服务器病毒库版本
void AntiVirusWork::readSrvVdbVersion()
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_dataInterFaceServer, "GetVirusSrvVersion");
    GET_MESSAGE_VALUE(QString, sVersion, msg);
    m_sSrvVdbVer = sVersion;

    if (checkIsNeedUpdate()) {
        m_needUpdate = true;
    } else {
        m_needUpdate = false;
    }
}

// 接收服务器病毒库版本
void AntiVirusWork::acceptVirusSrvVersion(const QString &sVersion)
{
    m_sSrvVdbVer = sVersion;
    QTimer::singleShot(3000, this, SLOT(acceptVirusSrvVersionTimer()));
}

// 接受服务器病毒库版本延时
void AntiVirusWork::acceptVirusSrvVersionTimer()
{
    if (EnginType::Rising == getVriusType()) {
        // 判断返回值是否正常
        if ("error" != m_sSrvVdbVer && checkIsNeedUpdate()) {
            m_needUpdate = true;
        } else {
            m_needUpdate = false;
        }
    } else {
        // 格式校验
        if (4 == m_sSrvVdbVer.split(".").count() && checkIsNeedUpdate()) {
            m_needUpdate = true;
        } else {
            m_needUpdate = false;
        }
    }

    Q_EMIT notifyUpdateAntiVirusHomeUI();
    Q_EMIT haveNewVdb(m_needUpdate);

    m_vdbChecking = false;
}

// 检查是否需要更新
bool AntiVirusWork::checkIsNeedUpdate()
{
    if (EnginType::Rising == getVriusType()) {
        // 判断返回值是否正常
        if (m_sSrvVdbVer.toInt() > m_sLocalVdbVer.toInt()) {
            return true;
        }
    } else {
        // 格式校验
        if (DVersionNumber::compare(DVersionNumber::fromString(m_sSrvVdbVer), DVersionNumber::fromString(m_sLocalVdbVer)) > 0) {
            return true;
        }
    }
    return false;
}

// 离线导入后设置病毒库查杀版本号
void AntiVirusWork::setVirusImportVersion(const QStringList sVersionList)
{
    for (int i = 0; i < sVersionList.count(); ++i) {
        if (!sVersionList.at(i).contains(".")) {
            // 设置瑞星病毒库本地版本
            m_gsetting->SetValue(RISING_LOCAL_VERSION, sVersionList.at(i));
            if (EnginType::Rising == getVriusType()) {
                m_needUpdate = false;
                readLocalVdbVersion();

                Q_EMIT notifyUpdateAntiVirusHomeUI();
                Q_EMIT haveNewVdb(m_needUpdate);
            }
        } else {
            m_gsetting->SetValue(AH_LOCAL_VERSION, sVersionList.at(i));
            if (EnginType::Ahprotector == getVriusType()) {
                m_needUpdate = false;
                readLocalVdbVersion();

                Q_EMIT notifyUpdateAntiVirusHomeUI();
                Q_EMIT haveNewVdb(m_needUpdate);
            }
        }
    }
}

// 查询版本号是否为最新
void AntiVirusWork::queryVersionStatus()
{
    updateVirusSrvVersion();
}

// 更新版本
void AntiVirusWork::updateVirusSrvVersion()
{
    m_vdbChecking = true;
    // 设置病毒库更新地址地址
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "SetVriusUpdateAddress", getVirusAddress());
    // 查询病毒库版本
    DBUS_NOBLOCK_INVOKE(m_virusScanServer, "QueryVersion");
}

QString AntiVirusWork::getVirusAddress()
{
    /* 默认病毒库升级地址修改为gsetting报错，代码不允许包含未公开的网站地址 */
    QString sVirusAddress = m_gsetting->GetValue(VRIUS_UPDATE_ADDRESS_DEFAULT).toString();

    // 获得自定义大小是否勾选
    bool isCheck = m_gsetting->GetValue(EXECUTE_VRIUS_UPDATE_ADDRESS).toBool();
    // 获得升级地址信息
    QString sAddress = m_gsetting->GetValue(VRIUS_UPDATE_ADDRESS).toString();
    if (isCheck && !sAddress.isEmpty()) {
        sVirusAddress = sAddress;
    }

    return sVirusAddress;
}

void AntiVirusWork::showScanFromMainWindow(int type, const QString &path)
{
    DBUS_NOBLOCK_INVOKE(m_mainWindowServer, "ShowScanByTypeAndPath", type, path);
}

bool AntiVirusWork::showNormalNotification(const QString &msg)
{
    return Utils::showNormalNotification(m_notifDBusInter, msg);
}
